﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace APRIL
{
    /// <summary>
    /// APR编码
    /// </summary>
    class AprEncode
    {
        /// <summary>
        /// tag data
        /// </summary>
        public string tag { get; set; }
        public AprEncode()
        {
        }
        public AprEncode(string s)
        {
            tag = s;
        }
        public byte[] Encode()
        {
            byte[] data = new byte[] { };
            string s1 = tag.Substring(0, 22);
            string s2 = tag.Substring(22, 22);
            string header = "AAB";
            for (int index = 0; index < 8 / 2; index++)
            {
                string strCode = string.Format("{0}012B9{1}00", 2 * index, s1);
                data = data.Concat(ToArray(Direct(header) + CXZ_code(Manchester(Check(Direct(strCode)))))).ToArray();
                strCode = string.Format("{0}012B9{1}00", 2 * index + 1, s2);
                data = data.Concat(ToArray(Direct(header) + CXZ_code(Manchester(Check(Direct(strCode)))))).ToArray();
            }
            return data;
        }

        /// <summary>
        /// 直接编码
        /// </summary>
        /// <returns></returns>
        public string Direct(string s)
        {
            string strCode = "";
            try
            {
                for (int index = 0; index < s.Length; index++)
                {
                    int er = ValueHelper.HexChar2Value(s.Substring(index, 1));
                    int IntCode = Int32.Parse(ValueHelper.DtoB(er));//ValueHelper.ToErJin(er);
                    strCode += IntCode.ToString("d04");
                }
                return strCode;
            }
            catch
            {
                return strCode;
            }
        }

        private string Check(string s)
        {
            string strCodeTemp = s;
            string strCheck = "00000";
            string strCode = strCodeTemp + strCheck;
            try
            {
                int Cout = 0;
                for (int index = 0; index < strCode.Length; index++)
                {
                    if (index < 1 || index > 120)
                    {
                        continue;
                    }
                    string Temp = strCode.Substring(index, 1);
                    if (Temp.Equals("1"))
                    {
                        Cout++;
                    }

                }
                strCheck = Int32.Parse(ValueHelper.DtoB(Cout)).ToString("d05");
                strCode = strCodeTemp + strCheck;
                return strCode;
            }
            catch
            {
                return strCode;
            }
        }

        /// <summary>
        /// 直接编码
        /// </summary>
        /// <returns></returns>
        private byte[] Direct_code(string s)
        {
            byte[] data = new byte[] { };
            List<byte> values = new List<byte>();
            for (int i = 0; i < s.Length; i++)
            {
                int b = int.Parse(s.Substring(i, 1), System.Globalization.NumberStyles.HexNumber);
                values.Add((byte)b);
            }
            data = values.ToArray();
            return data;
        }
        /// <summary>
        /// 曼彻斯特编码
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string Manchester(string s)
        {
            string strCode = "";
            try
            {
                for (int index = 0; index < s.Length; index++)
                {
                    string Temp = s.Substring(index, 1);
                    if (Temp.Equals("0"))
                        strCode += "01";
                    else
                        strCode += "10";
                }
                return strCode;
            }
            catch
            {
                return strCode;
            }
        }
        /// <summary>
        /// 曼彻斯特编码
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string Manchester(byte[] data)
        {
            int bitN = 4;
            string strCode = "";
            try
            {
                for (int index = 0; index < data.Length; index++)
                {
                    int vb = (int)data[index];
                    for (int i = 0; i < bitN; i++)
                    {
                        //循环处理，0->01 ,1->10
                        int dir_code = ValueHelper.getIntegerSomeBit(vb, bitN - 1 - i);
                        if (dir_code == 0)
                            strCode += "01";
                        else
                            strCode += "10";
                    }
                }

                return strCode;
            }
            catch
            {
                return strCode;
            }
        }
        /// <summary>
        /// 自推算法
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private string CXZ_code(string s)
        {
            int Count = s.Length;
            string strCode = "00";
            int Length = 2;

            /*   
               string pres0 = "";
               string pres1 = "";
               for (int i = 0; i < Count; i++)
               {
                   if (s.Substring(i, 1) == "0")
                   {
                       if (pres0 == "00")
                       {
                           strCode += "11";
                           pres0 = "11";
                       }
                       else
                       {
                           strCode += "00";
                           pres0 = "00";
                       }
                   }
                   else
                   {
                       if (pres1 == "10")
                       {
                           strCode += "01";
                           pres1 = "01";
                       }
                       else
                       {
                           strCode += "10";
                           pres1 = "10";
                       }
                   }
               }
            */
            for (int i = 1; i < Count; i++)
            {
                Length = strCode.Length;
                if (s.Substring(i, 1) == "0")
                {
                    if (strCode.Substring(Length - 1, 1) == "0")
                    {
                        strCode += "11";

                    }
                    else
                    {
                        strCode += "00";

                    }
                }
                else
                {
                    if (strCode.Substring(Length - 1, 1) == "1")
                    {
                        strCode += "01";

                    }
                    else
                    {
                        strCode += "10";

                    }
                }
            }
            return strCode;
        }

        public override string ToString()
        {
            return base.ToString();
        }

        private byte[] ToArray(string s)
        {
            int Count = s.Length / 8;
            byte[] data = new byte[] { };
            List<byte> values = new List<byte>();
            for (int i = 0; i < Count; i++)
            {
                int b = int.Parse(string.Format("{0:X}", Convert.ToInt32(s.Substring(i * 8, 8), 2)), System.Globalization.NumberStyles.HexNumber);
                values.Add((byte)b);

            }
            data = values.ToArray();
            return data;
        }
    }
}
